
import chain.IDialogEventHandler;
import filter.ConversationManager;
import java.io.IOException;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import json.ElementJson;
import json.ElementJSonSerializer;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;

/**
 *
 * @author dakhoa
 * @version 1.0
 */
public abstract class AbstractController extends MultiActionController {

//    public static final String AJAX_REQUEST = "AJAX_REQUEST";
    public static final String AJAX_REQUEST = "X-Requested-With";
    private Map<String, String> actionViewMap;
    private String defaultView;
    private DialogHandler dialogHandler;
    private String currentAction;
    private HttpServletRequest request;
    private HttpServletResponse response;
    private ElementJSonSerializer jsonSerializer;

    @Override
    public ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
        this.request = request;
        this.response = response;
        this.jsonSerializer = ElementJSonSerializer.getInstance();

        ParameterMethodNameResolver methodNameResolver = (ParameterMethodNameResolver) getMethodNameResolver();
        currentAction = methodNameResolver.getHandlerMethodName(request);

        ModelAndView mv = super.handleRequestInternal(request, response);
        resolveView(methodNameResolver, mv);

        jsonSerializer.serialize(response.getWriter(), mv, isIsAjxReq());

        return mv;
    }

    public ModelAndView showView(HttpServletRequest request, HttpServletResponse response) {
        return mvTemplate();
    }

    protected void registerJson(ElementJson... elements) {
        jsonSerializer.add(elements);
    }

    protected void unRegisterJson(ElementJson... elements) {
        jsonSerializer.remove(elements);
    }

    protected ModelAndView mvTemplate() {
        return new ModelAndView();
    }

    protected void handleDialog(IDialogEventHandler dialogEventHandler) {
        try {
            dialogHandler.processDialog(request, response, dialogEventHandler, currentAction);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    protected Map<String, Object> getFlowScope() {
        return ConversationManager.getInstance().getFlowScope();
    }

    public boolean isIsAjxReq() {
        return "XMLHttpRequest".equalsIgnoreCase(request.getHeader("X-Requested-With"))
            && (null == request.getParameter("tab"));
    }

    public void setDialogHandler(DialogHandler dialogHandler) {
        this.dialogHandler = dialogHandler;
    }

    private void resolveView(ParameterMethodNameResolver methodNameResolver, ModelAndView mv) {
        if (!isIsAjxReq()) {

            mv.setViewName(defaultView);

            if (!methodNameResolver.getDefaultMethodName().equals(currentAction)
                && actionViewMap != null) {

                String view = actionViewMap.get(currentAction);
                if (view != null) {
                    mv.setViewName(view);
                } else {
                    System.out.println("No view mapping for: " + currentAction + ", use default instead");
                }
            }
        }
    }

    public void setActionViewMap(Map<String, String> actionViewMap) {
        this.actionViewMap = actionViewMap;
    }

    public void setDefaultView(String defaultView) {
        this.defaultView = defaultView;
    }
}
